package com.danawa.watcher.front.serviceStrategy;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;

import com.danawa.watcher.util.StringUtil;
import com.danawa.watcher.util.WatcherEnumUtil;
import com.danawa.watcherApi.database.command.common.Condition;
import com.danawa.watcherApi.database.command.common.Operator;
import com.danawa.watcherApi.database.command.common.Order;
import com.danawa.watcherApi.database.domain.BaseProduct;
import com.danawa.watcherApi.database.domain.InflowProduct;
import com.danawa.watcherApi.database.domain.MemberTracking;
import com.danawa.watcherApi.database.domain.PriceHistory;
import com.danawa.watcherApi.database.domain.Type.State;
import com.danawa.watcherApi.database.service.WatcherService;
import com.danawa.watcherApi.parser.ShopParser;
import com.danawa.watcherApi.parser.ShopParserFactory;
import com.danawa.watcherApi.parser.ShopParserFactory.Checker;

public class WatcherServiceStrategy {
	
	@Autowired 
	WatcherService watcherService;
	
	/**
	 * url로 해당 데이타 파싱
	 * @param String
	 * @return
	 */
	public Map<String, String> dataParserMap(String url)  {
		Map<String, String> parserData = null;
		
		if(url != null && !"".equals(url)){
			ShopParser parser = ShopParserFactory.create(Checker.SHOP_ELEVEN);
			parser.addNext(ShopParserFactory.create(Checker.SHOP_SSG));
			try {
				parserData = parser.handler(url);
				parserData.put("siteUrl", url);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return parserData;
	}
	
	/**
	 * 최초 상품등록 프로세스
	 */
	public int addProductProcess(Map<String, String> parserData ){
		//기준 상품 등록
		int baseProductSeq = this.setBaseProduct(parserData);
		
		
		//유입상품등록
		int inflowProductSeq = 0;
		if( baseProductSeq > 0){
			inflowProductSeq = this.setInflowProduct(baseProductSeq, parserData);
		}
		
		//가격히스토리 등록
		if( inflowProductSeq > 0){
			this.setPriceHistory(inflowProductSeq, parserData);
		}
		
		return baseProductSeq;
	}
	
	/**
	 * 가격 변동 프로세스
	 */
	public int updateProductProcess(BaseProduct baseProduct ){
		int baseProductSeq = 0;
		if(baseProduct != null && baseProduct.getInflowProducts().size() > 0){
			for(InflowProduct inflowProduct : baseProduct.getInflowProducts()){
				Map<String, String> parserData = this.dataParserMap(inflowProduct.getLink());
				if(parserData != null){
					boolean isProd = false;
					int maximume		= inflowProduct.getMaximumPrice();	//최고가
					int minimum 		= inflowProduct.getMinimumPrice();	//최저가
					int present 		= inflowProduct.getPresentPrice();		//현재가
					int parserPresent = StringUtil.toInt(parserData.get(ShopParser.PROD_PRICE));		// 파싱 현재가
					
					//최고가
					if(maximume < parserPresent){
						inflowProduct.setMaximumPrice(parserPresent);
						isProd = true;
					}
					//최저가
					if(minimum > parserPresent){
						inflowProduct.setMinimumPrice(parserPresent);
						isProd = true;
					}
					//현재가
					if(present != parserPresent){
						inflowProduct.setPresentPrice(parserPresent);
						isProd = true;
					}
					
					//가격변동시 업데이트
					if(isProd){
						//기준 상품 업데이트
						this.setInflowProduct(inflowProduct);
						
						//가격 히스토리 업데이트
						this.setPriceHistory(inflowProduct.getInflowProductSeq(), parserData);
					}
				}
			}
		}
		return baseProductSeq;
	}
	
	
	
	/**
	 * 상품리스트 프로세스
	 */
	public BaseProduct selectProductProcess(int baseProductSeq){
		BaseProduct baseProduct = new BaseProduct();
		try {
			baseProduct = watcherService.getBaseProductWithInflowProducts(baseProductSeq);
			
			if(baseProduct.getInflowProducts().size() > 0){
				for(InflowProduct inflowProduct : baseProduct.getInflowProducts()){
					PriceHistory priceHistory = new PriceHistory();
					priceHistory.setOperator(Operator.EQUAL, "inflowProductSeq", inflowProduct.getInflowProductSeq());
					priceHistory.setOrder(Order.DESC, "priceHistorySeq");
					priceHistory.setOffset(0);
					priceHistory.setLimit(5);
					inflowProduct.setPriceHistories(watcherService.getPriceHistories(priceHistory));
				}
			}
		} catch (Throwable e) {
			e.printStackTrace();
		}
		
		return baseProduct;
	}
	
	/**
	 * 상품에 따른 회원 트래킹 정보
	 * @param baseProduct
	 * @return
	 */
	public List<MemberTracking>  memberTracking(int memberSeq, BaseProduct baseProduct ){
		MemberTracking memberTracking = new MemberTracking();
		List<MemberTracking> memberTrackings = new ArrayList<MemberTracking>();
		if(baseProduct.getInflowProducts().size() > 0){
			for(InflowProduct inflowProducts : baseProduct.getInflowProducts()){
				memberTracking = new MemberTracking();
				memberTracking.setOperator(Operator.EQUAL, "memberSeq", memberSeq);
				memberTracking.setOperator(Operator.EQUAL, "inflowProductSeq", inflowProducts.getInflowProductSeq());
				List<MemberTracking> memberTrackingTemp = new ArrayList<MemberTracking>();
				try {
					memberTrackingTemp = watcherService.getMemberTrackings(memberTracking);
				} catch (Throwable e) {
					e.printStackTrace();
				}
				if(memberTrackingTemp.size() > 0){
					memberTrackings.add(memberTrackingTemp.get(0));
				}
			}
		}
		return memberTrackings;
	}
	
	
	/**
	 * 기준 상품 저장
	 * @param parserData
	 * @return
	 */
	private int setBaseProduct(Map<String, String> parserData ){
		int result = 0;
		BaseProduct baseProduct = new BaseProduct();
		baseProduct.setKey( parserData.get(ShopParser.PROD_CODE));
		baseProduct.setName(parserData.get(ShopParser.PROD_NAME));
		baseProduct.setImageUrl(parserData.get(ShopParser.PROD_IMAGE));
		baseProduct.setMallType(WatcherEnumUtil.mallType(parserData.get(ShopParser.SHOP_NAME)));
		baseProduct.setStateType(State.ON_SALE);
		
		try {
			result = watcherService.setBaseProduct(baseProduct);
			if(result > 0){
				result = baseProduct.getBaseProductSeq();
			}
		} catch (Throwable e) {
			e.printStackTrace();
		}
		return result; 	
	}
	
	/**
	 * 기준상품 업데이트
	 * @param inflowProduct
	 * @return
	 */
	private int setInflowProduct(InflowProduct inflowProduct){
		int result = 0;
		try {
			inflowProduct.setUpdateDateTime(new Date());
			result = watcherService.setInflowProduct(inflowProduct);
		} catch (Throwable e) {
			e.printStackTrace();
		}
		return result;
	}
	
	/**
	 * 유입상품  저장
	 * @param parserData
	 * @return
	 */
	private int setInflowProduct(int baseProductSeq, Map<String, String> parserData ){
		int result = 0;
		
		if(baseProductSeq > 0){
			int basePrice = StringUtil.toInt(parserData.get(ShopParser.PROD_BASE_PRICE));
			int prodPrice = StringUtil.toInt(parserData.get(ShopParser.PROD_PRICE));
			InflowProduct inflowProduct = new InflowProduct();
			inflowProduct.setBaseProductSeq(baseProductSeq);
			inflowProduct.setSiteType(WatcherEnumUtil.siteType(""));
			inflowProduct.setLink(parserData.get("siteUrl"));
			inflowProduct.setFixedPrice(basePrice);
			inflowProduct.setPresentPrice(prodPrice);
			inflowProduct.setMaximumPrice(prodPrice);
			inflowProduct.setMinimumPrice(prodPrice);
			inflowProduct.setTrackingCount(0);
			inflowProduct.setLikeCount(0);
			inflowProduct.setCreateDateTime(new Date());
			inflowProduct.setUpdateDateTime(new Date());
			
			try {
				result = watcherService.setInflowProduct(inflowProduct);
				if(result > 0){
					result = inflowProduct.getInflowProductSeq();
				}
			} catch (Throwable e) {
				e.printStackTrace();
			}
		}
		
		return result;
		
	}
	
	/**
	 * 가격 히스토리 저장
	 * @param parserData
	 * @return
	 */
	private int setPriceHistory(int inflowProductSeq, Map<String, String> parserData ){
		int result = 0;
		if(inflowProductSeq > 0){
			int prodPrice = StringUtil.toInt(parserData.get(ShopParser.PROD_PRICE));
			
			PriceHistory priceHistory = new PriceHistory();
			priceHistory.setInflowProductSeq(inflowProductSeq);
			priceHistory.setPrice(prodPrice);
			priceHistory.setInputDateTime(new Date());

			try {
				result = watcherService.setPriceHistory(priceHistory);
				if(result > 0){
					result = priceHistory.getPriceHistorySeq();
				}
			} catch (Throwable e) {
				e.printStackTrace();
			}
		}
		
		return result;
	}
	

	
	
}
